package cn.u313.lymusic.adapter

import android.content.Context
import androidx.recyclerview.widget.RecyclerView
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.MutableLiveData

abstract class BaseRecyclerViewAdapter<T, VH : RecyclerView.ViewHolder>(context: Context) :
    RecyclerView.Adapter<VH>() {

    constructor(context: Context, list: MutableList<T>) : this(context) {
        mData=list
        mLiveData.setValue(mData)
    }

    private val mContext: Context = context

    //用于存储列表数据，保证ViewModel和Adapter的数据是同一个引用
    protected var mData: MutableList<T> = mutableListOf()

    protected val mLiveData  = MutableLiveData<MutableList<T>>()
    //每一项的点击监听器
    var onItemClickListener:((view: View, bean: T, position: Int)->Unit)?=null

    //item长按监听器
    var onItemLongClickListener:((view: View, bean: T, position: Int)->Boolean)?=null

    fun getMContext(): Context = mContext

    final override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH =
        onCreateVH(parent, viewType)

    abstract fun onCreateVH(parent: ViewGroup, viewType: Int): VH

    /**
     * 使用onBindDataForItem()方法代替
     *
     * @param holder
     * @param position
     */
    @Deprecated("使用onBindDataForItem()代替")
    final override fun onBindViewHolder(holder: VH, position: Int) {
        onBindDataForItem(holder, position, mData)
        setItemListeners(holder, position)
    }

    /**
     * 为子项布局视图填充数据
     *
     * @param viewHolder ViewHolder实例
     * @param bean       bean实例
     * @param position   位置
     */
    abstract fun onBindDataForItem(viewHolder: VH, position: Int, mData: MutableList<T>)

    /**
     * 设置Item里面按钮的监听器
     *
     * @param holder   视图views
     * @param t        实例对象
     * @param position 位置
     */
    protected open fun setItemListeners(holder: VH, position: Int) {
        holder.itemView.setOnClickListener { v ->
            onItemClickListener?.invoke(v,mData[position],position)
        }
        holder.itemView.setOnLongClickListener { v ->
            onItemLongClickListener?.invoke(v, mData[position], position)?:return@setOnLongClickListener true
        }
    }

    /*********************  数 据  *************************/

    override fun getItemCount(): Int {
        return mData.size
    }

    /**
     * 获取item实例
     *
     * @param position 位置
     * @return bean实例
     */
    open fun getItemBean(position: Int): T {
        return mData[position]
    }

    /**
     * 根据位置来添加数据
     *
     * @param position 位置，使用getItemCount来获取
     * @param listData 需要添加的数据
     */
    open fun addListData(position: Int, listData: List<T>?) {
        if (listData != null) {
            mData.addAll(position, listData)
        }
    }

    /**
     * 设置列表数据，此方法是初始化时调用
     * 因为ListData会覆盖原来的所有数据
     *
     * 不会改变原来数据源的引用，只会替换数据
     *
     * @param listData 列表数据
     */
    open fun setListData(listData: ArrayList<T>) {
        mData.clear()
        mData.addAll(listData)
        //更新数据  方案：将数据库数据清空，重新添加到数据库汇总
        notifyDataSetChanged()
    }

    /**
     * 根据位置来添加一项数据
     *
     * @param data 数据
     */
    open fun addData(data: T) {
        if (!mData.contains(data)) {
            mData.add(data)
            notifyDataSetChanged()
        }
    }

    /**
     * 根据位置来添加一项数据
     *
     * @param position 位置，使用getItemCount来获取
     * @param data     数据
     */
    open fun addData(position: Int, data: T) {
        if (!mData.contains(data)) {
            mData.add(position, data)
            notifyItemInserted(position)
        }
    }

    /**
     * 根据位置移除数据
     *  remove：把数据从list中remove掉，
     *  notifyItemRemoved：显示动画效果
     *  notifyItemRangeChanged：对于被删掉的位置及其后range大小范围内的view进行重新onBindViewHolder,
     *
     *  因为函数里面的传入的参数position，它是在进行onBind操作时确定的，在删除单项后，
     *  已经出现在画面里的项不会再有调用onBind机会，这样它保留的position一直是未进行删除操作前的position值。
     * @param position 位置
     */
    open fun removeData(position: Int) {
        if (position >= 0 && position < mData.size) {
            mData.removeAt(position)
            notifyItemRemoved(position)
            notifyItemRangeChanged(position, itemCount)
        }
    }

    /**
     * 获取数据集合
     *
     * @return 集合数据
     */
    open fun getListData(): List<T> {
        return mData
    }

    open fun getLiveData(): MutableLiveData<MutableList<T>> {
        return mLiveData
    }

    /**
     * 清除数据
     */
    open fun clearData() {
        mData.clear()
    }
}